<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>rare_terms 聚合 | ElasticSearch 7.7 权威指南中文版</title>
	<meta name="keywords" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <meta name="description" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
	<script>
	var _link = 'search-aggregations-bucket-rare-terms-aggregation.html';
    </script>
</head>
<body>
<div class="main-container">
    <section id="content">
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-aggregations-bucket-rare-terms-aggregation.html" rel="nofollow" target="_blank">https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-aggregations-bucket-rare-terms-aggregation.html</a>, 原文档版权归 www.elastic.co 所有<br/>本地英文版地址: <a href="../en/search-aggregations-bucket-rare-terms-aggregation.html" rel="nofollow" target="_blank">../en/search-aggregations-bucket-rare-terms-aggregation.html</a></div>
                        <!-- start body -->
                  <div class="page_header">
<strong>重要</strong>: 此版本不会发布额外的bug修复或文档更新。最新信息请参考 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" rel="nofollow">当前版本文档</a>。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch 权威指南 [7.7]</a></span>
»
<span class="breadcrumb-link"><a href="search-aggregations.html">聚合</a></span>
»
<span class="breadcrumb-link"><a href="search-aggregations-bucket.html">桶(bucket)聚合</a></span>
»
<span class="breadcrumb-node">rare_terms 聚合</span>
</div>
<div class="navheader">
<span class="prev">
<a href="search-aggregations-bucket-range-aggregation.html">« range 聚合</a>
</span>
<span class="next">
<a href="search-aggregations-bucket-reverse-nested-aggregation.html">reverse_nested 聚合 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="search-aggregations-bucket-rare-terms-aggregation"></a>稀有词项(rare_terms)聚合
</h2>
</div></div></div>
<p>
一个多桶聚合，基于值源，用于查找“稀有”的词项，即位于分布长尾且不常用的词项。

从概念上讲，这类似于按<code class="literal">_count</code>升序排序的<code class="literal">terms</code>聚合。

正如<a class="xref" href="search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-order" title="Order">terms聚合文档</a>中所指出的，实际上按计数升序对<code class="literal">terms</code>聚合进行排序会产生极大的误差。

相反，应该使用<code class="literal">rare_terms</code>聚合。
</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_syntax_2"></a>语法
</h3>
</div></div></div>
<p>孤立地看，<code class="literal">rare_terms</code>聚合如下所示：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
    "rare_terms": {
        "field": "the_field",
        "max_doc_count": 1
    }
}</pre>
</div>
<div class="table">
<p class="title"><strong>表 6. <code class="literal">rare_terms</code> 参数</strong></p>
<div class="table-contents">
<table border="1" cellpadding="4px" summary="rare_terms Parameters">
<colgroup>
<col class="col_1">
<col class="col_2">
<col class="col_3">
<col class="col_4">
</colgroup>
<tbody>
<tr>
<td align="left" valign="top"><p>参数名称</p></td>
<td align="left" valign="top"><p>描述</p></td>
<td align="left" valign="top"><p>是否必须</p></td>
<td align="left" valign="top"><p>默认值</p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">field</code></p></td>
<td align="left" valign="top"><p>希望搜索稀有词项的字段</p></td>
<td align="left" valign="top"><p>必须的</p></td>
<td align="left" valign="top"><p></p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">max_doc_count</code></p></td>
<td align="left" valign="top"><p>一个词项应该出现在文档中的最大数量。</p></td>
<td align="left" valign="top"><p>可选</p></td>
<td align="left" valign="top"><p><code class="literal">1</code></p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">precision</code></p></td>
<td align="left" valign="top"><p>内部布谷鸟顾虑器(CuckooFilters)的精度。精度越小，近似值越精确，但内存使用率越高。 但是不能小于 <code class="literal">0.00001</code></p></td>
<td align="left" valign="top"><p>可选</p></td>
<td align="left" valign="top"><p><code class="literal">0.01</code></p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">include</code></p></td>
<td align="left" valign="top"><p>应包含在聚合中的词项</p></td>
<td align="left" valign="top"><p>可选</p></td>
<td align="left" valign="top"><p></p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">exclude</code></p></td>
<td align="left" valign="top"><p>应从聚合中排除的词项</p></td>
<td align="left" valign="top"><p>可选</p></td>
<td align="left" valign="top"><p></p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">missing</code></p></td>
<td align="left" valign="top"><p>如果文档中没有正在聚合的字段，则应使用的值</p></td>
<td align="left" valign="top"><p>可选</p></td>
<td align="left" valign="top"><p></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<p>示例：</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "aggs" : {
        "genres" : {
            "rare_terms" : {
                "field" : "genre"
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/502.console"></div>
<p>响应：</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...
    "aggregations" : {
        "genres" : {
            "buckets" : [
                {
                    "key" : "swing",
                    "doc_count" : 1
                }
            ]
        }
    }
}</pre>
</div>
<p>
在这个例子中，我们看到的唯一的桶是“swing”桶，因为它是唯一出现在一个文档中的词项。

如果我们将<code class="literal">max_doc_count</code>增加到<code class="literal">2</code>，我们将看到更多的桶：
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "aggs" : {
        "genres" : {
            "rare_terms" : {
                "field" : "genre",
                "max_doc_count": 2
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/503.console"></div>
<p>现在显示了“jazz”词项，其<code class="literal">doc_count</code>为2：</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...
    "aggregations" : {
        "genres" : {
            "buckets" : [
                {
                    "key" : "swing",
                    "doc_count" : 1
                },
                {
                    "key" : "jazz",
                    "doc_count" : 2
                }
            ]
        }
    }
}</pre>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="search-aggregations-bucket-rare-terms-aggregation-max-doc-count"></a>最大文档数量
</h3>
</div></div></div>
<p>
参数<code class="literal">max_doc_count</code>用于控制一个词项可以拥有的文档数量的上限。

像<code class="literal">terms</code>聚合一样，<code class="literal">rare_terms</code>聚合没有大小限制。

这意味着将返回符合<code class="literal">max_doc_count</code>标准的词项。

聚合以这种方式运行，以避免困扰<code class="literal">terms</code>聚合的升序问题。
</p>
<p>
然而，这确实意味着如果选择不正确，可能会返回大量结果。

为了限制这种设置的危险性，<code class="literal">max_doc_count</code>的最大值是<code class="literal">100</code>。
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="search-aggregations-bucket-rare-terms-aggregation-max-buckets"></a>最大桶数限制
</h3>
</div></div></div>
<p>
由于其工作方式的原因，rare_terms 聚合比其他聚合更容易超出<code class="literal">search.max_buckets</code>软限制。

当聚合收集结果时，<code class="literal">max_bucket</code>软限制基于每个分片进行评估。

一个词项在一个分片上可能是“稀有的”，但是一旦所有分片结果合并在一起，它就变得“不稀有”了。

这意味着单个分片倾向于收集比真正罕见的更多的桶，因为它们只有自己的本地视图。

这个列表最终在协调节点上被删减为正确的、更小的稀有词项列表……但是一个分片可能已经触发了<code class="literal">max_buckets</code>软限制并中止了请求。
</p>
<p>
当对可能包含许多“罕见”术语的字段进行聚合时，你可能需要增加<code class="literal">max_buckets</code>软限制的值。

或者，你可能需要找到一种方法来过滤结果，以返回更少的稀有值(更小的时间跨度、按类别过滤等)，或者重新评估你对“稀有”的定义(例如，如果某个东西出现100,000次，它真的“稀有”吗？)
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="search-aggregations-bucket-rare-terms-aggregation-approximate-counts"></a>文档数量是近似值
</h3>
</div></div></div>
<p>
确定数据集中“罕见的”词项的简单方法是将所有值放在一个映射中，随着每个文档被访问，计数递增，然后返回底部的<code class="literal">n</code>行。

这甚至不能扩展到中等大小的数据集。 

一种仅保留来自每个分片的“前n”个值(也称为<code class="literal">terms</code>聚合)的分片方法会失败，因为问题的长尾特性意味着，如果不简单地收集来自所有分片的所有值，就不可能找到“前n”个底部的值。
</p>
<p>相反，rare_terms聚合使用不同的近似算法：</p>
<div class="olist orderedlist">
<ol class="orderedlist">
<li class="listitem">
第一次看到值时，它们会被放置在一个映射中。
</li>
<li class="listitem">
该词项每增加一次，映射中的计数器就加一
</li>
<li class="listitem">
如果计数器大于<code class="literal">max_doc_count</code>阈值，则从映射中移除该词项，并将其放入<a href="https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf" class="ulink" target="_top" rel="nofollow">布谷鸟过滤器(CuckooFilter)</a>中
</li>
<li class="listitem">
每个词项都要参考布谷鸟过滤器(CuckooFilter)。

如果该值在过滤器内，则已知它已经高于阈值并被跳过。
</li>
</ol>
</div>
<p>
执行后，值的映射是<code class="literal">max_doc_count</code>阈值下的“稀有”词项的映射。

然后这个映射和布谷鸟过滤器与所有其他分片合并。

如果有大于阈值的此昂(或出现在不同分片的布谷鸟过滤器中),该词项将从合并列表中删除。

最终的值映射作为“稀有”词项返回给用户。
</p>
<p>
布谷鸟过滤器有可能返回误报(它们可以说某个值存在于它们的集合中，而实际上它并不存在)。

由于布谷鸟过滤器用于查看某项是否超过阈值，这意味着布谷鸟过滤器的误报将错误地认为某个值是常见的，而实际上它并不是常见的(从而将其从桶的最终列表中排除)。

实际上，这意味着聚合表现出假阴性行为，因为过滤器的使用与人们通常认为的近似集合成员草图的方式“相反”。
</p>
<p>布谷鸟过滤器在论文中有更详细的描述：</p>
<p>
<a href="https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf" class="ulink" target="_top">Fan, Bin, et al. "Cuckoo filter: Practically better than bloom."</a> 第10届ACM国际新兴网络实验和技术会议录。美国计算机学会，2014年。
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_precision"></a>精度
</h3>
</div></div></div>
<p>
虽然内部的布谷鸟过滤器本质上是近似的，但假阴性率可以通过参数<code class="literal">precision</code>来控制。

这允许用户用更多的运行时内存来换取更精确的结果。
</p>
<p>
默认精度是<code class="literal">0.001</code>，最小精度值是(例如，最精确和最大的内存开销)是<code class="literal">0.00001</code>。

下面是一些图表，展示了不同词项的精确度和数量如何影响聚合的准确性。
</p>
<p>
X轴显示聚合看到的唯一值的数量，Y轴显示误差百分比。

每条折线代表一个“稀有”条件(从一个稀有物品到100,000个稀有物品)。

例如，橙色的“10”线条表示100万 ~ 2000万个唯一值中有10个值是“罕见的”(<code class="literal">doc_count == 1</code>)，其余值的<code class="literal">doc_count &gt; 1</code>
</p>
<p>第一张图显示的是精度为<code class="literal">0.01</code>的情况：</p>
<p><span class="image"><img src="../static/images/rare_terms/accuracy_01.png" alt="accuracy 01"></span></p>
<p>以及精度<code class="literal">0.001</code> (默认)的情况：</p>
<p><span class="image"><img src="../static/images/rare_terms/accuracy_001.png" alt="accuracy 001"></span></p>
<p>最后一个是精度为<code class="literal">0.0001</code>的情况：</p>
<p><span class="image"><img src="../static/images/rare_terms/accuracy_0001.png" alt="accuracy 0001"></span></p>
<p>
默认精度为<code class="literal">0.001</code>，在测试条件下保持 &lt; 2.5%的精度，随着唯一值数量的增加，精度以受控的线性方式缓慢下降。
</p>
<p>
默认精度为<code class="literal">0.001</code>，内存配置为<code class="literal">1.748⁻⁶ * n</code>字节，其中<code class="literal">n</code>是聚合看到的唯一值的数量(也可以粗略估计，例如2000万个唯一值大约是30MB内存)。

无论选择哪种精度，内存使用量都与唯一值的数量成线性关系，精度仅影响内存配置的斜率，如下图所示：
</p>
<p><span class="image"><img src="../static/images/rare_terms/memory.png" alt="memory"></span></p>
<p>
相比之下，2000万个桶的等效 terms 聚合大约为 <code class="literal">20m * 69b == ~1.38gb</code>(69字节是对空桶成本的非常乐观的估计，远远低于熔断器所占的成本)。

因此，尽管<code class="literal">rare_terms</code>聚合成本相对较高，但其数量级仍然小于等价的 terms 聚合
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_filtering_values"></a>对值进行过滤
</h3>
</div></div></div>
<p>
可以过滤将用于创建桶的值。

这可以使用基于正则表达式字符串或精确值数组的<code class="literal">include</code>和<code class="literal">exclude</code>参数来完成。

此外，<code class="literal">include</code>子句可以使用<code class="literal">partition</code>表达式进行过滤。
</p>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_filtering_values_with_regular_expressions"></a>使用正则表达式对值进行过滤
</h4>
</div></div></div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "aggs" : {
        "genres" : {
            "rare_terms" : {
                "field" : "genre",
                "include" : "swi*",
                "exclude" : "electro*"
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/504.console"></div>
<p>
在上面的例子中，将为所有以<code class="literal">swi</code>开头的标签创建桶，除了那些以 <code class="literal">electro</code>开头的标签(因此标签<code class="literal">swing</code>将被聚合，而不是<code class="literal">electro_swing</code>)。

<code class="literal">include</code>正则表达式将确定“允许”聚合哪些值，而<code class="literal">exclude</code> 将确定不应该聚合的值。

当两者都被定义时，<code class="literal">exclude</code>优先，这意味着首先计算<code class="literal">include</code>，然后才计算<code class="literal">exclude</code>。
</p>
<p>
语法与<a class="xref" href="regexp-syntax.html" title="Regular expression syntax">正则查询</a>相同。
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_filtering_values_with_exact_values"></a>使用精确值对值进行过滤
</h4>
</div></div></div>
<p>
对于基于精确值的匹配，<code class="literal">include</code>和<code class="literal">exclude</code>参数可以简单地接受一个字符串数组，这些字符串表示在索引中找到的词项:
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "aggs" : {
        "genres" : {
             "rare_terms" : {
                 "field" : "genre",
                 "include" : ["swing", "rock"],
                 "exclude" : ["jazz"]
             }
         }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/505.console"></div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_missing_value_16"></a>缺失的值
</h3>
</div></div></div>
<p>
参数<code class="literal">missing</code>定义应该如何处理有缺失值的文档。 默认情况下，它们将被忽略，但也可以将它们视为有一个值。
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "aggs" : {
        "genres" : {
             "rare_terms" : {
                 "field" : "genre",
                 "missing": "N/A" <a id="CO237-1"></a><i class="conum" data-value="1"></i>
             }
         }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/506.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO237-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>在<code class="literal">tags</code>字段中没有值的文档将与具有<code class="literal">N/A</code>值的文档落入同一个桶中。</p>
</td>
</tr>
</table>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_nested_rareterms_and_scoring_sub_aggregations"></a>嵌套、稀有词项和评分子聚合
</h3>
</div></div></div>
<p>
rear_terms 聚合必须以<code class="literal">breadth_first</code><span class="remark">(广度优先)</span>模式运行，因为它需要在文档计数阈值被突破时修剪词项。

这个要求意味着 rear_terms 聚合与需要 <code class="literal">depth_first</code><span class="remark">(深度优先)</span> 的某些聚合组合不兼容。

特别是，对<code class="literal">nested</code><span class="remark">(嵌套)</span>子聚合进行评分会强制整个聚合树以<code class="literal">depth_first</code><span class="remark">(深度优先)</span> 模式运行。

因为 rear_terms 聚合和无法处理<code class="literal">depth_first</code><span class="remark">(深度优先)</span>，就会抛出一个异常。
</p>
<p>
一个具体的例子，如果<code class="literal">rare_terms</code>聚合是<code class="literal">nested</code>聚合的子聚合，并且<code class="literal">rare_terms</code>的一个子聚合需要文档评分(比如<code class="literal">top_hits</code>聚合)，就会抛出一个异常。
</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="search-aggregations-bucket-range-aggregation.html">« range 聚合</a>
</span>
<span class="next">
<a href="search-aggregations-bucket-reverse-nested-aggregation.html">reverse_nested 聚合 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>